{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "5aa9aaea",
   "metadata": {},
   "source": [
    "模拟数据集中的动作,就是传统的深度学习而已"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "29091de6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(20000, (tensor([ 0.4413,  0.8974, -0.7139]), tensor([-1.0650])))"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "\n",
    "#封装数据集\n",
    "class Dataset(torch.utils.data.Dataset):\n",
    "\n",
    "    def __init__(self):\n",
    "        import numpy as np\n",
    "        data = np.loadtxt('连续动作.txt')\n",
    "        self.state = torch.FloatTensor(data[:, :3])\n",
    "        self.action = torch.FloatTensor(data[:, -1]).reshape(-1, 1)\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.state)\n",
    "\n",
    "    def __getitem__(self, i):\n",
    "        return self.state[i], self.action[i]\n",
    "\n",
    "\n",
    "dataset = Dataset()\n",
    "\n",
    "len(dataset), dataset[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f78563c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2500,\n",
       " [tensor([[ 0.9726,  0.2323,  0.0481],\n",
       "          [ 0.9957,  0.0925,  1.3494],\n",
       "          [ 0.9849,  0.1728,  0.4492],\n",
       "          [ 0.9974,  0.0718, -1.6214],\n",
       "          [ 0.9719,  0.2356, -0.0301],\n",
       "          [ 0.9742,  0.2259, -0.2024],\n",
       "          [ 0.9607, -0.2774, -0.6714],\n",
       "          [ 0.9857,  0.1687,  0.4045]]),\n",
       "  tensor([[-0.8233],\n",
       "          [-0.8886],\n",
       "          [-0.6845],\n",
       "          [ 0.1982],\n",
       "          [-0.7237],\n",
       "          [-0.1562],\n",
       "          [ 1.0381],\n",
       "          [-0.5526]])])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#数据加载器\n",
    "loader = torch.utils.data.DataLoader(dataset=dataset,\n",
    "                                     batch_size=8,\n",
    "                                     shuffle=True,\n",
    "                                     drop_last=True)\n",
    "\n",
    "len(loader), next(iter(loader))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3ae67dc1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 1])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "model = torch.nn.Sequential(\n",
    "    torch.nn.Linear(3, 64),\n",
    "    torch.nn.ReLU(),\n",
    "    torch.nn.Linear(64, 64),\n",
    "    torch.nn.ReLU(),\n",
    "    torch.nn.Linear(64, 1),\n",
    "    torch.nn.Tanh(),\n",
    ")\n",
    "\n",
    "model(torch.randn(2, 3)).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fe6b3443",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 0.038115568459033966\n",
      "1 0.03741789981722832\n",
      "2 0.06291048228740692\n",
      "3 0.08614323288202286\n",
      "4 0.10068434476852417\n",
      "5 0.038076382130384445\n",
      "6 0.05754101648926735\n",
      "7 0.06762734055519104\n",
      "8 0.06364182382822037\n",
      "9 0.09015730768442154\n"
     ]
    }
   ],
   "source": [
    "#训练\n",
    "def train():\n",
    "    model.train()\n",
    "    optimizer = torch.optim.Adam(model.parameters(), lr=2e-4)\n",
    "    loss_fn = torch.nn.MSELoss()\n",
    "\n",
    "    for epoch in range(10):\n",
    "        for i, (state, action) in enumerate(loader):\n",
    "            out = model(state)\n",
    "\n",
    "            loss = loss_fn(out, action)\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "            optimizer.zero_grad()\n",
    "\n",
    "        if epoch % 1 == 0:\n",
    "            print(epoch, loss.item())\n",
    "\n",
    "\n",
    "train()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c81c0cdc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 300x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import gym\n",
    "\n",
    "\n",
    "#定义环境\n",
    "class MyWrapper(gym.Wrapper):\n",
    "\n",
    "    def __init__(self):\n",
    "        env = gym.make('Pendulum-v1', render_mode='rgb_array')\n",
    "        super().__init__(env)\n",
    "        self.env = env\n",
    "        self.step_n = 0\n",
    "\n",
    "    def reset(self):\n",
    "        state, _ = self.env.reset()\n",
    "        self.step_n = 0\n",
    "        return state\n",
    "\n",
    "    def step(self, action):\n",
    "        state, reward, terminated, truncated, info = self.env.step(\n",
    "            [action * 2])\n",
    "        over = terminated or truncated\n",
    "\n",
    "        #偏移reward,便于训练\n",
    "        reward = (reward + 8) / 8\n",
    "\n",
    "        #限制最大步数\n",
    "        self.step_n += 1\n",
    "        if self.step_n >= 200:\n",
    "            over = True\n",
    "\n",
    "        return state, reward, over\n",
    "\n",
    "    #打印游戏图像\n",
    "    def show(self):\n",
    "        from matplotlib import pyplot as plt\n",
    "        plt.figure(figsize=(3, 3))\n",
    "        plt.imshow(self.env.render())\n",
    "        plt.show()\n",
    "\n",
    "\n",
    "env = MyWrapper()\n",
    "\n",
    "env.reset()\n",
    "\n",
    "env.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "15cda860",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "169.6805284130523"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython import display\n",
    "import random\n",
    "\n",
    "\n",
    "#玩一局游戏并记录数据\n",
    "def play(show=False):\n",
    "    reward_sum = 0\n",
    "\n",
    "    state = env.reset()\n",
    "    over = False\n",
    "    while not over:\n",
    "        action = model(torch.FloatTensor(state).reshape(1, 3)).item()\n",
    "\n",
    "        #给动作添加噪声,增加探索\n",
    "        action += random.normalvariate(mu=0, sigma=0.2)\n",
    "\n",
    "        state, reward, over = env.step(action)\n",
    "        reward_sum += reward\n",
    "\n",
    "        if show:\n",
    "            display.clear_output(wait=True)\n",
    "            env.show()\n",
    "\n",
    "    return reward_sum\n",
    "\n",
    "\n",
    "#测试\n",
    "sum([play() for _ in range(20)]) / 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "85cf24b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 300x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "167.49010349876326"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "play(True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:pt39]",
   "language": "python",
   "name": "conda-env-pt39-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
